package com.example.uwe;

import com.example.uwe.model.*;
import com.example.uwe.service.AccommodationService;
import javafx.animation.FadeTransition;
import javafx.animation.ScaleTransition;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.util.Duration;

public class AccommodationController {
    private AccommodationService accommodationService;

    @FXML
    private ComboBox<String> hallComboBox;

    @FXML
    private Label totalRoomsLabel;

    @FXML
    private Label availableRoomsLabel;

    @FXML
    private Label offlineRoomsLabel;

    @FXML
    private Label requireCleaningLabel;

    @FXML
    private TextField hallNameField;

    @FXML
    private TextField phoneNumberField;

    @FXML
    private TextField managerField;

    @FXML
    private TableView<Accommodation> accommodationTable;

    @FXML
    private TableColumn<Accommodation, Integer> accommodationNumberColumn;

    @FXML
    private TableColumn<Accommodation, String> accommodationTypeColumn;

    @FXML
    private TableColumn<Accommodation, Double> rentalPriceColumn;

    @FXML
    private TableColumn<Accommodation, String> availabilityColumn;

    @FXML
    private TableColumn<Accommodation, String> cleaningStatusColumn;

    @FXML
    private TextField accommodationNumberField;

    @FXML
    private TextField typeField;

    @FXML
    private TextField priceField;

    @FXML
    private TextField occupancyField;
    
    @FXML
    private TextField descriptionField;

    @FXML
    private ComboBox<String> cleaningStatusComboBox;

    @FXML
    private TextField leaseNumberField;

    @FXML
    private TextField firstNameField;

    @FXML
    private TextField lastNameField;

    @FXML
    private TextField studentNumberField;

    @FXML
    private TextField mobileField;

    @FXML
    private Button createButton;

    @FXML
    private Button deleteButton;

    @FXML
    private TextField searchField;
    
    @FXML
    private Button searchButton;
    
    @FXML
    private Button clearSearchButton;

    private Hall currentHall;
    private Accommodation selectedAccommodation;

    public void setAccommodationService(AccommodationService accommodationService) {
        this.accommodationService = accommodationService;
        initializeUI();
    }

    private void initializeUI() {
        // 初始化宿舍下拉框
        ObservableList<String> hallNames = FXCollections.observableArrayList();
        for (Hall hall : accommodationService.getHalls()) {
            hallNames.add(hall.getName());
        }
        hallComboBox.setItems(hallNames);
        hallComboBox.getSelectionModel().selectFirst();

        // 初始化清洁状态下拉框
        cleaningStatusComboBox.setItems(FXCollections.observableArrayList(
                CleaningStatus.CLEAN.getDisplayName(),
                CleaningStatus.DIRTY.getDisplayName(),
                CleaningStatus.OFFLINE.getDisplayName()
        ));
        
        // 添加文本字段验证监听器
        setupTextFieldValidation();

        // 初始化表格列
        accommodationNumberColumn.setCellValueFactory(new PropertyValueFactory<>("accommodationNumber"));
        accommodationTypeColumn.setCellValueFactory(cellData -> 
            new SimpleStringProperty(cellData.getValue().getType().getDisplayName()));
        rentalPriceColumn.setCellValueFactory(new PropertyValueFactory<>("rentalPrice"));
        availabilityColumn.setCellValueFactory(cellData -> {
            Accommodation acc = cellData.getValue();
            if (!acc.isAvailable()) {
                return new SimpleStringProperty("Occupied");
            } else if (acc.getCleaningStatus() == CleaningStatus.CLEAN) {
                return new SimpleStringProperty("Available");
            } else if (acc.getCleaningStatus() == CleaningStatus.DIRTY) {
                return new SimpleStringProperty("Unavailable");
            } else {
                return new SimpleStringProperty("Unavailable");
            }
        });
        cleaningStatusColumn.setCellValueFactory(cellData -> 
            new SimpleStringProperty(cellData.getValue().getCleaningStatus().getDisplayName()));
        
        // 设置表格行样式
        accommodationTable.setRowFactory(tv -> {
            TableRow<Accommodation> row = new TableRow<>();
            row.itemProperty().addListener((obs, oldItem, newItem) -> {
                if (newItem != null) {
                    if (!newItem.isAvailable()) {
                        row.getStyleClass().add("status-unavailable");
                    } else if (newItem.getCleaningStatus() == CleaningStatus.CLEAN) {
                        row.getStyleClass().add("status-available");
                    } else if (newItem.getCleaningStatus() == CleaningStatus.OFFLINE) {
                        row.getStyleClass().add("status-offline");
                    }
                } else {
                    row.getStyleClass().removeAll("status-unavailable", "status-available", "status-offline");
                }
            });
            return row;
        });

        // 设置表格选择事件
        accommodationTable.getSelectionModel().selectedItemProperty().addListener(
                (observable, oldValue, newValue) -> onAccommodationSelected(newValue));

        // 添加表格双击事件
        accommodationTable.setOnMouseClicked(event -> {
            if (event.getClickCount() == 2 && accommodationTable.getSelectionModel().getSelectedItem() != null) {
                // 双击时添加高亮动画效果
                Node node = event.getPickResult().getIntersectedNode();
                // 向上查找TableRow节点
                while (node != null && !(node instanceof TableRow)) {
                    node = node.getParent();
                }
                if (node instanceof TableRow) {
                    TableRow<Accommodation> row = (TableRow<Accommodation>) node;
                    FadeTransition ft = new FadeTransition(Duration.millis(300), row);
                    ft.setFromValue(0.7);
                    ft.setToValue(1.0);
                    ft.setCycleCount(2);
                    ft.setAutoReverse(true);
                    ft.play();
                }
            }
        });

        // 为按钮添加悬停效果
        addButtonHoverEffect(createButton);
        addButtonHoverEffect(deleteButton);
        addButtonHoverEffect(searchButton);
        addButtonHoverEffect(clearSearchButton);
        
        // 加载默认宿舍数据
        loadHallData(hallComboBox.getValue());
    }

    @FXML
    private void onHallSelected() {
        String hallName = hallComboBox.getValue();
        if (hallName != null) {
            loadHallData(hallName);
        }
    }

    private void loadHallData(String hallName) {
        currentHall = accommodationService.getHallByName(hallName);
        if (currentHall != null) {
            // 更新宿舍信息
            hallNameField.setText(currentHall.getName());
            phoneNumberField.setText(currentHall.getPhoneNumber());
            managerField.setText(currentHall.getManagerName());

            // 更新统计信息
            totalRoomsLabel.setText(String.valueOf(currentHall.getTotalAccommodations()));
            availableRoomsLabel.setText(String.valueOf(currentHall.getAvailableAccommodations()));
            offlineRoomsLabel.setText(String.valueOf(currentHall.getOfflineAccommodations()));
            requireCleaningLabel.setText(String.valueOf(currentHall.getRequireCleaningAccommodations()));

            // 更新住宿表格
            accommodationTable.setItems(FXCollections.observableArrayList(
                    accommodationService.getAccommodationsByHall(currentHall)));
        }
    }

    private void onAccommodationSelected(Accommodation accommodation) {
        selectedAccommodation = accommodation;
        if (accommodation != null) {
            // 更新住宿信息字段
            accommodationNumberField.setText(String.valueOf(accommodation.getAccommodationNumber()));
            typeField.setText(accommodation.getType().getDisplayName());
            priceField.setText(String.valueOf(accommodation.getRentalPrice()));
            descriptionField.setText(accommodation.getDescription());
            
            cleaningStatusComboBox.setValue(accommodation.getCleaningStatus().getDisplayName());
            
            // 根据清洁状态和占用状态设置显示文本
            if (!accommodation.isAvailable()) {
                occupancyField.setText("Occupied");
            } else if (accommodation.getCleaningStatus() == CleaningStatus.CLEAN) {
                occupancyField.setText("Available");
            } else if (accommodation.getCleaningStatus() == CleaningStatus.DIRTY) {
                occupancyField.setText("Unavailable");
            } else {
                occupancyField.setText("Unavailable");
            }
            
            // 根据状态设置按钮可用性
            if (!accommodation.isAvailable()) {
                // 如果已占用，则禁用创建按钮，启用删除按钮
                createButton.setDisable(true);
                deleteButton.setDisable(false);
                
                // 查找租约信息
                RentalAgreement agreement = accommodationService.getRentalAgreementByAccommodation(accommodation);
                if (agreement != null) {
                    leaseNumberField.setText(String.valueOf(agreement.getLeaseNumber()));
                    firstNameField.setText(agreement.getFirstName());
                    lastNameField.setText(agreement.getLastName());
                    studentNumberField.setText(agreement.getStudentNumber());
                    mobileField.setText(agreement.getMobileNumber());
                }
            } else {
                // 如果未占用，则根据清洁状态设置创建按钮可用性
                createButton.setDisable(accommodation.getCleaningStatus() != CleaningStatus.CLEAN);
                deleteButton.setDisable(true);
                clearRentalFields();
            }
            
            // 更新创建按钮状态以应用验证
            updateCreateButtonState();
        } else {
            clearAccommodationFields();
            clearRentalFields();
            createButton.setDisable(true);
            deleteButton.setDisable(true);
        }
    }

    private void clearAccommodationFields() {
        accommodationNumberField.clear();
        typeField.clear();
        priceField.clear();
        occupancyField.clear();
        descriptionField.clear();
        cleaningStatusComboBox.setValue(null);
    }

    private void clearRentalFields() {
        leaseNumberField.clear();
        firstNameField.clear();
        lastNameField.clear();
        studentNumberField.clear();
        mobileField.clear();
        
        // 重置字段样式
        firstNameField.setStyle("");
        lastNameField.setStyle("");
        studentNumberField.setStyle("");
        mobileField.setStyle("");
    }

    @FXML
    private void onCreateRentalAgreement() {
        if (selectedAccommodation == null) {
            return;
        }

        String firstName = firstNameField.getText();
        String lastName = lastNameField.getText();
        String studentNumber = studentNumberField.getText();
        String mobile = mobileField.getText();

        if (firstName.isEmpty() || lastName.isEmpty() || studentNumber.isEmpty() || mobile.isEmpty()) {
            showAlert("错误", "所有字段都必须填写。");
            return;
        }
        
        // Validate first name and last name (only letters allowed)
        if (!firstName.matches("[a-zA-Z]+")) {
            showAlert("输入错误", "名字只能包含字母，不能包含数字或符号。");
            return;
        }
        
        if (!lastName.matches("[a-zA-Z]+")) {
            showAlert("输入错误", "姓氏只能包含字母，不能包含数字或符号。");
            return;
        }
        
        // Validate student number and mobile (only numbers allowed)
        if (!studentNumber.matches("\\d+")) {
            showAlert("输入错误", "学生号只能包含数字。");
            return;
        }
        
        if (!mobile.matches("\\d+")) {
            showAlert("输入错误", "手机号只能包含数字。");
            return;
        }

        RentalAgreement agreement = accommodationService.createRentalAgreement(
                selectedAccommodation, firstName, lastName, studentNumber, mobile);

        if (agreement != null) {
            leaseNumberField.setText(String.valueOf(agreement.getLeaseNumber()));
            occupancyField.setText("Occupied");
            createButton.setDisable(true);
            deleteButton.setDisable(false);
            
            // 刷新UI
            refreshCurrentView();
        } else {
            showAlert("错误", "无法创建租赁协议。房间可能不可用或需要清洁。");
        }
    }

    @FXML
    private void onDeleteRentalAgreement() {
        if (leaseNumberField.getText().isEmpty()) {
            return;
        }

        try {
            long leaseNumber = Long.parseLong(leaseNumberField.getText());
            boolean deleted = accommodationService.deleteRentalAgreement(leaseNumber);

            if (deleted) {
                clearRentalFields();
                
                // 根据清洁状态设置显示文本
                if (selectedAccommodation.getCleaningStatus() == CleaningStatus.CLEAN) {
                    occupancyField.setText("Available");
                    createButton.setDisable(false);
                } else if (selectedAccommodation.getCleaningStatus() == CleaningStatus.DIRTY) {
                    occupancyField.setText("Unavailable");
                    createButton.setDisable(true);
                } else {
                    occupancyField.setText("Unavailable");
                    createButton.setDisable(true);
                }
                
                deleteButton.setDisable(true);
                
                // 刷新UI
                refreshCurrentView();
            } else {
                showAlert("错误", "无法删除租赁协议。");
            }
        } catch (NumberFormatException e) {
            showAlert("错误", "租赁号码无效。");
        }
    }

    @FXML
    private void onUpdateCleaningStatus() {
        if (selectedAccommodation == null) {
            return;
        }

        String statusStr = cleaningStatusComboBox.getValue();
        CleaningStatus status = null;

        for (CleaningStatus cs : CleaningStatus.values()) {
            if (cs.getDisplayName().equals(statusStr)) {
                status = cs;
                break;
            }
        }

        if (status != null) {
            accommodationService.updateCleaningStatus(selectedAccommodation, status);
            cleaningStatusColumn.getCellData(selectedAccommodation);
            
            // 如果房间有租约且状态设为离线，则禁用创建按钮
            createButton.setDisable(!selectedAccommodation.isAvailable() || status != CleaningStatus.CLEAN);
            
            // 刷新UI
            refreshCurrentView();
        }
    }
    
    @FXML
    private void onUpdateDescription() {
        if (selectedAccommodation == null) {
            return;
        }
        
        String description = descriptionField.getText();
        accommodationService.updateDescription(selectedAccommodation, description);
        
        // 刷新UI
        refreshCurrentView();
    }

    private void refreshCurrentView() {
        if (currentHall != null) {
            loadHallData(currentHall.getName());
            
            // 重新选择当前选中的住宿
            if (selectedAccommodation != null) {
                for (Accommodation acc : accommodationTable.getItems()) {
                    if (acc.getAccommodationNumber() == selectedAccommodation.getAccommodationNumber()) {
                        accommodationTable.getSelectionModel().select(acc);
                        break;
                    }
                }
            }
        }
    }

    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        
        // 自定义对话框样式
        DialogPane dialogPane = alert.getDialogPane();
        dialogPane.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
        dialogPane.getStyleClass().add("alert-dialog");
        
        // 添加动画效果
        Stage stage = (Stage) dialogPane.getScene().getWindow();
        stage.setOpacity(0.0);
        
        // 淡入动画
        FadeTransition fadeIn = new FadeTransition(Duration.millis(300), dialogPane);
        fadeIn.setFromValue(0.0);
        fadeIn.setToValue(1.0);
        
        stage.setOnShown(e -> {
            stage.setOpacity(1.0);
            fadeIn.play();
        });
        
        alert.showAndWait();
    }
    
    // 添加按钮悬停效果
    private void addButtonHoverEffect(Button button) {
        if (button == null) return;
        
        button.setOnMouseEntered(e -> {
            ScaleTransition st = new ScaleTransition(Duration.millis(150), button);
            st.setToX(1.05);
            st.setToY(1.05);
            st.play();
        });
        
        button.setOnMouseExited(e -> {
            ScaleTransition st = new ScaleTransition(Duration.millis(150), button);
            st.setToX(1.0);
            st.setToY(1.0);
            st.play();
        });
    }
    
    @FXML
    private void onSearch() {
        String searchText = searchField.getText().trim();
        if (searchText.isEmpty()) {
            return;
        }
        
        try {
            int accommodationNumber = Integer.parseInt(searchText);
            Accommodation accommodation = accommodationService.getAccommodationByNumber(accommodationNumber);
            
            if (accommodation != null) {
                // 显示该宿舍楼
                hallComboBox.setValue(accommodation.getHall().getName());
                loadHallData(accommodation.getHall().getName());
                
                // 在表格中只显示这一个住宿
                ObservableList<Accommodation> singleAccommodation = FXCollections.observableArrayList(accommodation);
                accommodationTable.setItems(singleAccommodation);
                
                // 选中该住宿
                accommodationTable.getSelectionModel().select(accommodation);
                onAccommodationSelected(accommodation);
            } else {
                showAlert("搜索结果", "未找到编号为 " + accommodationNumber + " 的住宿。");
            }
        } catch (NumberFormatException e) {
            showAlert("输入错误", "请输入有效的住宿编号（数字）。");
        }
    }
    
    @FXML
    private void onClearSearch() {
        searchField.clear();
        
        // 恢复显示当前宿舍楼的所有住宿
        if (currentHall != null) {
            loadHallData(currentHall.getName());
        }
    }

    // 设置文本字段验证监听器
    private void setupTextFieldValidation() {
        // 名字和姓氏只允许字母
        firstNameField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.isEmpty() && !newValue.matches("[a-zA-Z]*")) {
                firstNameField.setStyle("-fx-border-color: red;");
                createButton.setDisable(true);
            } else {
                firstNameField.setStyle("");
                updateCreateButtonState();
            }
        });
        
        lastNameField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.isEmpty() && !newValue.matches("[a-zA-Z]*")) {
                lastNameField.setStyle("-fx-border-color: red;");
                createButton.setDisable(true);
            } else {
                lastNameField.setStyle("");
                updateCreateButtonState();
            }
        });
        
        // 学生号和手机号只允许数字
        studentNumberField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.isEmpty() && !newValue.matches("\\d*")) {
                studentNumberField.setStyle("-fx-border-color: red;");
                createButton.setDisable(true);
            } else {
                studentNumberField.setStyle("");
                updateCreateButtonState();
            }
        });
        
        mobileField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.isEmpty() && !newValue.matches("\\d*")) {
                mobileField.setStyle("-fx-border-color: red;");
                createButton.setDisable(true);
            } else {
                mobileField.setStyle("");
                updateCreateButtonState();
            }
        });
    }
    
    // 更新创建按钮状态
    private void updateCreateButtonState() {
        if (selectedAccommodation == null || !selectedAccommodation.isAvailable() || 
                selectedAccommodation.getCleaningStatus() != CleaningStatus.CLEAN) {
            createButton.setDisable(true);
            return;
        }
        
        // 检查所有字段是否有效
        boolean isFirstNameValid = firstNameField.getText().matches("[a-zA-Z]*");
        boolean isLastNameValid = lastNameField.getText().matches("[a-zA-Z]*");
        boolean isStudentNumberValid = studentNumberField.getText().matches("\\d*");
        boolean isMobileValid = mobileField.getText().matches("\\d*");
        
        // 检查所有字段是否已填写且有效
        boolean allFieldsFilled = !firstNameField.getText().isEmpty() && 
                                !lastNameField.getText().isEmpty() && 
                                !studentNumberField.getText().isEmpty() && 
                                !mobileField.getText().isEmpty();
        
        createButton.setDisable(!(isFirstNameValid && isLastNameValid && 
                                isStudentNumberValid && isMobileValid && allFieldsFilled));
    }
}